第一章:从一个简单的Web应用开始

正所谓:“工欲善其事,必先利其器”,在正式开始设计并开发我们的轻量级Java Web 框架之前,有必要掌握以下技能:

  • 使用 IDEA 搭建并开发 Java 项目;
  • 使用 Maven 自动化构建 Java 项目;
  • 使用 Git 管理项目源代码;

使用 IDEA 创建 Maven 项目

创建 IDEA 项目

我们无需单独下载 Maven,更不用将其集成到 IDEA 中,因为 IDEA 默认已经将其整合了。在 IDEA 中创建 Maven 项目非常简单,只需要按照以下步骤进行即可:

  1. 单击 “Create New Project” 按钮,弹出 “New Project” 对话框。
  2. 选择 Maven 选项,单击 “Next” 按钮
  3. 输入 GroupId (org.smart4j)、ArtifactID(chapter1)、Version(1.0.0),单击 “Next” 按钮。
  4. 输入 Project name(chapter1)、Project location(C:\chapter1),单击 “Finish” 按钮。

这里需要说明的是,其中 GroupId 建议为网站域名的倒排方式,以便确保唯一性,类似于 Java 的包名。

按照以上操作,只需片刻之间,IDEA 就创建了一个基于 Maven 的目录结构,如图 所示。

调整 Maven 配置

当打开 Maven 项目配置文件(pom.xml)后,看到的应该是这样的配置:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.smart4j</groupId>
<artifactId>chapter1</artifactId>
<version>1.0-SNAPSHOT</version>


</project>

以上只是 pom.xml 的基本配置,下面需要为它添加一些常用配置。

首先,需要统一源代码的编码方式,否则使用 Maven 编译源代码的时候就会出现相关警告。一般情况下,我们都使用 UTF-8 进行编码,需要添加的配置如下:

1
2
3
4
5
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
...

除了需要统一源代码编码方式以外,还需要统一源代码与编译输出的JDK版本。由于书中使用 JDK1.6 进行的开发,因此需要如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
<build>
<plugins>
<!-- Compile -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
...

所有的 plugin 都需要添加到 build>plugins 标签下, Maven 插件或下文中所出现的 Maven 的依赖都来自于 Maven 中央仓库,可以通过以下链接访问:

http://search.maven.org/

如果说上面添加的两个配置是必需的,那么下面的这个配置应该就是可选的。如果在使用 Maven 打包时想要跳过单元测试,那么可以添加如下插件:

1
2
3
4
5
6
7
8
9
<!-- Test -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>

至此,一个 Maven 项目就搭建完毕了,下面我们就要在这个项目中添加有关的 Java Web 的代码。

搭建 Web 项目框架

转为 Java Web 项目

目前,在 pom.xml 中还没有任何的 Maven 依赖(dependency),随后会添加一些 Java Web 所需的依赖,只不过在添加这些依赖之前,有必要先将这个 Maven 项目调整为 Web 项目结构。

提示:可以简单地将 Maven 理解为 jar 包,只不过 Maven 依赖具备传递性,只需配置某个依赖,就能自动获取该依赖的相关依赖。

只需要按照以下三步即可实现:

  1. File > Project Structure > Facets > + > Web > chapter1
  2. Deployment Descriptors > Edit > chapter1/src/main/webapp/WEB-INF/web.xml
  3. Web Resources Directories > Edit > chapter1/src/main/webapp

此时,IDEA 会自动生成 src/main/webapp/WEB-INF/web.xml 文件

至此,Java Web 项目创建完毕。实际上,使用 Servlet3.0+ 框架是可以省略 web.xml 文件的,因为 Servlet 无须再 web.xml 里配置,只需通过 Java 注解的方式来配置即可。

添加 Java Web 的 Maven 依赖

由于 Web 项目是需要打 war 包的,因此必须在 pom.xml 文件里设置 packaging 为 war(默认为 jar),配置如下:

1
<packaging>war</packaging>

接下来就需要添加 Java Web 所需的 Servlet、JSP、JSTL 等依赖了,添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<dependencies>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- JSP -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>

需要说明的是:

  1. maven 依赖的 “三坐标” (groupId、artifactId、version)必须提供。
  2. 如果某些依赖只需参与编译,而无须参与打包(例如,Tomcat 自带了 Servlet 与 JSP 所对应的 jar 包),可将其 scope 设置为 provided。
  3. 如果某些依赖只是运行时需要,但无需参与编译(例如,JSTL 的 jar 包),可将其 scope 设置为 runtime。

为了便于阅读 以下是 pom.xml 的完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.smart4j</groupId>
<artifactId>chapter1</artifactId>
<version>1.0-SNAPSHOT</version>

<packaging>war</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- JSP -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>

<build>
<plugins>
<!-- Compile -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<!-- Test -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<!-- Tocmat -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/${project.artifactId}</path>
</configuration>
</plugin>
</plugins>
</build>

</project>

现在一个基于 Maven 的 Java Web 项目已搭建完毕,随后可进入具体的开发阶段。
学习任何技术,都需要从最容易入手的地方开始,下面我们利用一个简单的应用场景,一起学习 Servlet3.0+ 框架的使用方法。

编写一个简单的 Web 应用

编写 Servlet 类

我们要做的一件非常简单的事情:写一个 HelloServlet,接收 GET 类型的 /hello 请求,转发到 /WEB-INF/jsp/hello.jsp 页面,在 hello.jsp 页面上显示系统当前时间。

首先,需要在 Java 目录下,创建一个名为 org.smart4j.chapter1 的包

然后,在该包下创建一个 HelloServlet 的类,代码如下:

1
2
3
4
5
package org.smart4j.chapter1;

public class HelloServlet {

}

最后,我们需要为该类添加一些代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package org.smart4j.chapter1;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
* @author weilai
* @version 1.0.0 2018/8/22
*/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentTime = dateFormat.format(new Date());
req.setAttribute("currentTime", currentTime);
req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req, resp);
}
}

编写 JSP 页面

在 webapp 目录下创建 jsp 目录,并在该目录下创建 hello.jsp,编写如下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%--
Created by IntelliJ IDEA.
User: weilai
Date: 2018/8/22
Time: 下午8:25
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello</h1>
<h2>当前时间:${currentTime}</h2>
</body>
</html>

可见,我们使用了 JSTL 表达式来获取 HelloServlet 里传递过来的 currentTime 请求属性。

至此,所有代码编写完毕,我们就可以让这个 Web 应用跑起来!